package com.psy.counseling.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.psy.counseling.entity.Type;
import com.psy.counseling.entity.User;
import com.psy.counseling.entity.UserRole;
import com.psy.counseling.mapper.RolePermissionMapper;
import com.psy.counseling.mapper.UserMapper;
import com.psy.counseling.mapper.UserRoleMapper;
import com.psy.counseling.service.MailService;
import com.psy.counseling.service.TypeService;
import com.psy.counseling.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.psy.counseling.utils.DataEncode;
import com.psy.counseling.utils.IDUtils;
import com.psy.counseling.utils.ImportDataUtil;
import com.psy.counseling.utils.TimeUtil;
import com.psy.counseling.vo.*;
import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static org.apache.ibatis.ognl.OgnlOps.longValue;
import static org.apache.ibatis.ognl.OgnlOps.newInteger;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 梁学儒
 * @since 2022-05-31
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private RoleServiceImpl roleService;

    @Resource
    private PermissionServiceImpl permissionService;

    @Resource
    private TypeService typeService;

    @Resource
    private DataEncode dataEncode;

    @Resource
    private MailService mailService;

    @Value("${server.port}")
    private String port;


    /**
     * 登录页面
     * StpUtil.login() 中使用数据库主键
     * @param loginVo
     * @return Result <用户权限表>
     */
        public ResultVo login(LoginVo loginVo, HttpSession session) {
            QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", loginVo.getUsername());
        User user = userMapper.selectOne(wrapper);

        String sessionCode = String.valueOf(session.getAttribute("VerifyCode")).toLowerCase();
        System.out.println(sessionCode + "------");
        if(user == null) {
            return ResultVo.builder().code("500").msg("登陆失败!").data("用户不存在").build();
        } else if(!user.getStatus().equals(0)){
            return ResultVo.builder().code("500").msg("登陆失败!").data("账号未激活").build();
        } else{
            String pwd = dataEncode.decodeBae64(user.getPassword());
//            String pwd = user.getPassword();
            if(loginVo.getPassword().equals(pwd)) {
                if (loginVo.getCode().toUpperCase().equals(sessionCode.toUpperCase())) {
                    System.out.println("验证码正确！");
                    StpUtil.login(user.getId());
                    List<String> list = permissionService.getPermissionById();
                    List<String> list1 = roleService.getRoleListById();
                    Date date = new Date();
                    user.setLoginTime(TimeUtil.timeToStr(date));
                    userMapper.update(user,wrapper);
                    HashMap<String,Object> maps = new HashMap<>();
                    List<Object> objects = new ArrayList<>();
                    maps.put("id",StpUtil.getLoginIdAsInt());
                    maps.put("token",StpUtil.getTokenValueByLoginId(StpUtil.getLoginIdAsInt()));
                    maps.put("role",list1);
                    maps.put("permission",list);
                    objects.add(maps);
                    return ResultVo.builder().code("200").msg("登陆成功!").data(objects).build();
                } else {
                    return ResultVo.builder().code("500").msg("登陆失败!").data("验证码错误!!!").build();
                }

            } else {
                return ResultVo.builder().code("500").msg("登陆失败!").data("密码错误!!!").build();
            }
        }
    }

    /**
     * 注册页面
     * 如果该用户名已被使用， 则返回用户名已存在
     * 如果用户名不包含字母， 则返回用户名不规范
     * @param registerVo
     * @return result
     */

    public ResultVo register(RegisterVo registerVo) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, registerVo.getUsername());
        int cnt = this.count(wrapper);
        boolean isLetter = false;//定义一个boolean值，用来表示是否包含字母
        for(int i=0 ; i<registerVo.getUsername().length() ; i++){ //循环遍历字符串
            if(Character.isLetter(registerVo.getUsername().charAt(i))){   //用char包装类中的判断字母的方法判断每一个字符
                isLetter = true;
            }
        }
        if(cnt != 0) {
            return ResultVo.builder().code("500").msg("注册失败").data("该用户名已存在").build();
        }else if(!isLetter){
            return ResultVo.builder().code("500").msg("注册失败").data("用户名不包含字母").build();
        }
        String pwd = dataEncode.encodeBae64(registerVo.getPassword());
        String email=registerVo.getEmail();
        try {
            //获取激活码
            String emailCode = IDUtils.getUUID();
            //主题
            String subject = "来自心理社区的激活邮件";
            //上面的激活码发送到用户注册邮箱
            InetAddress localhost = InetAddress.getLocalHost();
            String context = "<a href=\"http://"+localhost.getHostAddress()+":"+port+"/user/checkCode/"+emailCode+"\">激活请点击:"+emailCode+"</a>";
            //发送激活邮件
            mailService.sendMimeMail (email,subject,context);
            User user=new User();
            user.setPassword(pwd).
                    setEmail(email).
                    setRealName(registerVo.getRealName()).
                    setActiveCode(emailCode).
                    setStatus(1);
                int res = userMapper.insert(user);
                if (res >= 1) {
                    UserRole userRole = new UserRole();
                    userRole.setRolId(longValue(3));
                    userRole.setId(user.getId());
                    userRoleMapper.insert(userRole);
                    return ResultVo.builder().code("200").msg("注册成功").data(user).build();
                } else {
                    return ResultVo.builder().code("500").msg("注册失败").data(null).build();
                }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.builder().code("400").msg("网络错误，请稍后再试").data(null).build();
        }
    }

    public ResultVo activation(String activeCode) {
        log.info(activeCode);
        //如果用户不等于null，把用户状态status修改为0
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("active_code",activeCode));
        if (user !=null){
            user.setStatus(0);
            //把code验证码清空，已经不需要了
            user.setActiveCode("");
            UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id",user.getId());
            // 1.user 中封装修改的属性值， updateWrapper 中封装修改的条件参数值
            if(update(user,updateWrapper)){
                return ResultVo.builder().code("200").msg("激活成功").data(null).build();
            }else {
                return ResultVo.builder().code("500").msg("激活失败").data(null).build();
            }
        }else {
            return ResultVo.builder().code("500").msg("用户不存在").data(null).build();
        }
    }

    public ResultVo updatePassword(UpdatePasswordVo updatePwdVo) {
        int id=StpUtil.getLoginIdAsInt();
        QueryWrapper<User> UserQW = new QueryWrapper<>();
        UserQW.eq("id",id);
        User user = userMapper.selectById(id);
        String oldPwd=dataEncode.encodeBae64(updatePwdVo.getOldPwd());
        String newPwd=dataEncode.encodeBae64(updatePwdVo.getNewPwd());
        log.info(oldPwd);
        if (oldPwd.equals(user.getPassword())
                &&updatePwdVo.getNewPwd().equals(updatePwdVo.getRePwd())) {
            user.setPassword(newPwd);
            int update = userMapper.update(user, UserQW);
            System.out.println(update);
            return ResultVo.builder().code("200").msg("修改成功").data(user).build();
        } else {
            return ResultVo.builder().code("400").msg("密码错误").data(null).build();
        }
    }

    /**
     * 添加用户
     * @param user
     * @return ResultVo
     */
    @Transactional
    public ResultVo addUser(User user,Long roleId){
        if(ObjectUtils.isEmpty(roleId)){
            return ResultVo.builder().code("400").msg("添加失败!").data("角色id不能为空").build();
        }else {
            LambdaQueryWrapper<User> UQW = new LambdaQueryWrapper<>();
            UQW.eq(User::getUsername,user.getUsername());
            int i = this.count(UQW);
            if (i>0){
                return ResultVo.builder().code("400").msg("添加失败!").data("此用户名已经被占用").build();
            }
            user.setPassword(dataEncode.encodeBae64(user.getPassword()));
            if(userMapper.insert(user)>=1){
                UserRole userRole = new UserRole();
                userRole.setRolId(longValue(roleId));
                userRole.setId(user.getId());
                log.info(String.valueOf(userRoleMapper.insert(userRole)));
                return ResultVo.builder().code("200").msg("添加成功!").data(user).build();
            }
            else {
                return ResultVo.builder().code("500").msg("添加失败!").data("系统错误").build();
            }
        }
    }

    /**
     * 删除用户
     * @param deleteVO
     * @return ResultVo
     */
    @Transactional
    public ResultVo deleteUser(DeleteVO deleteVO){
        if(ObjectUtils.isNotEmpty(deleteVO.getId())){
            if(this.removeById(deleteVO.getId())){
                return ResultVo.builder().code("200").msg("删除成功!").data(null).build();
            }
        }else if(ObjectUtils.isNotEmpty(deleteVO.getIds())){
            if(this.removeByIds(deleteVO.getIds())){
                return ResultVo.builder().code("200").msg("删除成功!").data(null).build();
            }
        }else {
            return ResultVo.builder().code("400").msg("删除失败!").data("id不能为空").build();
        }
        return ResultVo.builder().code("500").msg("删除失败!").data("系统错误").build();
    }

    /**
     * 查询用户
     * @param user
     * @param page
     * @param roleId
     * @return ResultVo
     */
    @Transactional
    public ResultVo listUsers(User user, PageVO page,Long roleId) {
        Page<User> firstVisitPage = new Page<>(page.getPageNum(),page.getPageSize());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<UserRole> URWrapper = new LambdaQueryWrapper<>();
        URWrapper.eq(ObjectUtils.isNotEmpty(roleId),UserRole::getRolId,roleId);
        List<UserRole> userRoles = userRoleMapper.selectList(URWrapper);
        List<Long> userIds = userRoles.stream().map(UserRole::getId).collect(Collectors.toList());
        queryWrapper.eq(ObjectUtils.isNotEmpty(user.getId()),User::getId,user.getId())
                .eq(ObjectUtils.isNotEmpty(user.getRealName()),User::getRealName,user.getRealName())
                .eq(ObjectUtils.isNotEmpty(user.getUsername()),User::getUsername,user.getUsername())
                .eq(ObjectUtils.isNotEmpty(user.getAge()),User::getAge,user.getAge())
                .eq(ObjectUtils.isNotEmpty(user.getSex()),User::getSex,user.getSex())
                .eq(ObjectUtils.isNotEmpty(user.getFaculty()),User::getFaculty,user.getFaculty())
                .in(ObjectUtils.isNotEmpty(roleId),User::getId,userIds);
        firstVisitPage = this.page(firstVisitPage,queryWrapper);
        return ResultVo.builder().code("200").msg("查询成功!").data(firstVisitPage).build();
    }

    /**
     * 修改用户信息
     * @param user
     * @return ResultVo
     */
    @Transactional
    public ResultVo updateUser(User user){
        if(ObjectUtils.isNotEmpty(user.getId())){
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("id",user.getId());
            User user1 = userMapper.selectById(user.getId());
            if(ObjectUtils.isNotEmpty(user.getUsername())){
                LambdaQueryWrapper<User> UQW = new LambdaQueryWrapper<>();
                UQW.eq(User::getUsername,user.getUsername());
                User user2 = userMapper.selectOne(UQW);
                if (!user2.getId().equals(user.getId())){
                    return ResultVo.builder().code("400").msg("修改失败!").data("此用户名已经被占用").build();
                }
                user1.setUsername(user.getUsername());
            }if(ObjectUtils.isNotEmpty(user.getSex())){
                user1.setSex(user.getSex());
            }if(ObjectUtils.isNotEmpty(user.getAge())){
                user1.setAge(user.getAge());
            }if(ObjectUtils.isNotEmpty(user.getRealName())){
                user1.setRealName(user.getRealName());
            }if(ObjectUtils.isNotEmpty(user.getTelephone())){
                user1.setTelephone(user.getTelephone());
            }if(ObjectUtils.isNotEmpty(user.getInfo())){
                user1.setInfo(user.getInfo());
            }
            if(userMapper.update(user1,wrapper)>0){
                return ResultVo.builder().code("200").msg("修改成功!").data(user1).build();
            }else {
                return ResultVo.builder().code("500").msg("修改失败!").data("系统错误").build();
            }
        }else {
            return ResultVo.builder().code("400").msg("修改失败!").data("用户id不能为空").build();
        }
    }

    /**
     * 设置用户角色
     * @param userRoleVo
     * @return ResultVo
     */
    @Transactional
    public ResultVo updateUserRole(UserRoleVo userRoleVo){
        if(ObjectUtils.isNotEmpty(userRoleVo.getUserId())&&ObjectUtils.isNotEmpty(userRoleVo.getRoleIds())){
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("id",userRoleVo.getUserId());
            userRoleMapper.delete(wrapper);
            UserRole userRole = new UserRole();
            userRole.setId(userRoleVo.getUserId());
            for(Long list : userRoleVo.getRoleIds()){
                userRole.setRolId(list);
                userRoleMapper.insert(userRole);
            }
            return ResultVo.builder().code("200").msg("修改成功!").data(userRoleVo).build();
        }else {
            return ResultVo.builder().code("400").msg("修改失败!").data("id不能为空").build();
        }
    }

    /**
     * 返回学院
     * @param
     * @return ResultVo
     */
    @Transactional
    public ResultVo getFaculty(){
            QueryWrapper<Type> wrapper = new QueryWrapper<>();
            wrapper.eq("type_info","学院");
            return ResultVo.builder().code("200").msg("查询成功!").data(typeService.list(wrapper)).build();
    }

    @Transactional
    @Override
    public ArrayList<Integer> importUsers(MultipartFile multipartFile) throws IOException {
        FileInputStream fileInputStream = (FileInputStream) multipartFile.getInputStream();
        ImportDataUtil importData = new ImportDataUtil(fileInputStream);
        this.saveBatch(importData.getImportSuccess());
        return importData.getImportError();
    }
}
